home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
214
/
mandelvroom
/
src
/
scroll.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
14KB
|
537 lines
/*
* MandelVroom 2.0
*
* (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
*
* All rights reserved.
*
* Permission is hereby granted to distribute this program's source
* executable, and documentation for non-comercial purposes, so long as the
* copyright notices are not removed from the sources, executable or
* documentation. This program may not be distributed for a profit without
* the express written consent of the author Kevin L. Clague.
*
* This program is not in the public domain.
*
* Fred Fish is expressly granted permission to distribute this program's
* source and executable as part of the "Fred Fish freely redistributable
* Amiga software library."
*
* Permission is expressly granted for this program and it's source to be
* distributed as part of the Amicus Amiga software disks, and the
* First Amiga User Group's Hot Mix disks.
*
* contents: this file contains the functions used to implement MandelVroom's
* pan command. It seems to have a bug when resizing pictures slightly
* smaller.
*/
#include "mandp.h"
static int ScrollHotX, ScrollHotY;
UBYTE ScrollOn = 1;
#ifdef TEMPWINDOW
#define SAFEBLIT
static struct NewWindow NewTemp = {
0,12, /* start position */
80,80, /* width, height */
(UBYTE) 0, (UBYTE) NORMALPEN,
MOUSEBUTTONS, /* IDCMP flags */
/* MandWind flags */
WINDOWDRAG | NOCAREREFRESH | SMART_REFRESH,
(struct Gadget *) NULL, /* first gadget */
(struct Image *) NULL, /* user checkmark */
(UBYTE *) NULL, /* Title */
(struct Screen *) NULL, /* pointer to screen */
(struct BitMap *) NULL, /* pointer to superbitmap */
20,20,-1,-1, /* sizing */
CUSTOMSCREEN /* type of screen */
};
static struct Window *TempWind;
#endif
ScrollPictCmd(Msg)
struct IntuiMessage *Msg;
{
struct Window *Window;
static struct Picture *Pict;
Window = Msg->IDCMPWindow;
Pict = (struct Picture *) Window->UserData;
switch( Msg->Class ) {
case NEWSIZE:
if (CurPict && (CurPict->Flags & SCROLL_HAPPENED)) {
MoveClipImage(CurPict);
}
break;
case MENUPICK:
switch( SUBNUM(Msg->Code) ) {
case SETSCROLL:
State = SCROLLPICTSTATE;
ThrowTask(CurPict);
if ( ! (CurPict->Flags & SCROLL_HAPPENED)) {
if ( AllocScrollTemp(CurPict) == UNSUCCESSFUL ) {
return;
}
SaveInitialImage(CurPict);
}
CurPict->Flags |= SCROLL_HAPPENED;
SetToPointer();
break;
case GENSCROLL:
if (CurPict && CurPict->Flags & SCROLL_HAPPENED) {
Generate(CurPict);
}
break;
case CANCELSCROLL:
ReColor(CurPict);
break;
}
break;
case MOUSEBUTTONS:
switch( Msg->Code ) {
case SELECTDOWN: /* start drag */
if (Pict == NULL || Pict != CurPict) {
return;
}
ScrollHotX = MouseX - CurPict->ImageLoc.Left;
ScrollHotY = MouseY - CurPict->ImageLoc.Top;
Scroll( CurPict);
ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
break;
case SELECTUP: /* stop slide */
ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
break;
}
break;
case MOUSEMOVE:
Scroll( CurPict);
break;
}
}
SaveInitialImage(Pict)
struct Picture *Pict;
{
#ifdef SAFEBLIT
SafeClipBlit(Pict->Window, Pict->LeftMarg, Pict->TopMarg,
TempWind, 0, 0,
Pict->CountX, Pict->CountY,
0xc0, __LINE__);
#else
ClipBlit(Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
&Pict->ScrollRp, 0, 0,
Pict->CountX, Pict->CountY,
0xc0);
#endif
}
Scroll( Pict )
struct Picture *Pict;
{
CalcNewLoc(Pict,MouseX,MouseY); /* figure out location of new image */
MoveClipImage(Pict);
}
CalcNewLoc(Pict, MouseX, MouseY)
register struct Picture *Pict;
int MouseX, MouseY;
{
/* set new ImageLoc */
Pict->ImageLoc.Top = MouseY - ScrollHotY;
Pict->ImageLoc.Left = MouseX - ScrollHotX;
Pict->ImageLoc.Bot = Pict->ImageLoc.Top + Pict->CountY;
Pict->ImageLoc.Right = Pict->ImageLoc.Left + Pict->CountX;
}
MoveClipImage(Pict)
register struct Picture *Pict;
{
struct Window *Window;
struct RastPort *wind_Rp, *tmp_Rp;
register int POLeft, PORight, POTop, POBot;
struct Rect SaveRect;
struct Rect DispRect;
Window = Pict->Window;
SaveRect = Pict->ClipImage; /* struct assign */
DispRect.Left = Pict->LeftMarg;
DispRect.Top = Pict->TopMarg;
DispRect.Right = Window->Width - Pict->RightMarg - 1;
DispRect.Bot = Window->Height - Pict->BotMarg - 1;
if (Pict->ImageLoc.Left > DispRect.Right ||
Pict->ImageLoc.Top > DispRect.Bot ||
Pict->ImageLoc.Right < DispRect.Left ||
Pict->ImageLoc.Bot < DispRect.Top ) {
return;
}
if (Pict->ImageLoc.Left < DispRect.Left) {
Pict->ClipImage.Left = DispRect.Left;
POLeft = -Pict->ImageLoc.Left + Pict->LeftMarg;
} else {
Pict->ClipImage.Left = Pict->ImageLoc.Left;
POLeft = 0;
}
if (Pict->ImageLoc.Top < DispRect.Top) {
Pict->ClipImage.Top = DispRect.Top;
POTop = -Pict->ImageLoc.Top + Pict->TopMarg;
} else {
Pict->ClipImage.Top = Pict->ImageLoc.Top;
POTop = 0;
}
if (Pict->ImageLoc.Right <= DispRect.Right) {
Pict->ClipImage.Right = Pict->ImageLoc.Right;
PORight = Pict->CountX-1;
} else {
Pict->ClipImage.Right = DispRect.Right;
PORight = DispRect.Right - Pict->ImageLoc.Left;
}
if (Pict->ImageLoc.Bot <= DispRect.Bot) {
Pict->ClipImage.Bot = Pict->ImageLoc.Bot;
POBot = Pict->CountY - 1;
} else {
Pict->ClipImage.Bot = DispRect.Bot;
POBot = DispRect.Bot - Pict->ImageLoc.Top;
}
wind_Rp = Window->RPort;
#ifdef TEMPWINDOW
tmp_Rp = TempWind->RPort;
#else
tmp_Rp = &Pict->ScrollRp;
#endif
if (POLeft < PORight && POTop < POBot) {
/* Now copy temp rastport data to window */
#ifdef SAFEBLIT
SafeClipBlit(TempWind, POLeft, POTop, Window,
Pict->ClipImage.Left, Pict->ClipImage.Top,
PORight - POLeft + 1, POBot - POTop + 1, 0xc0,
__LINE__);
#else
ClipBlit(tmp_Rp, POLeft, POTop, wind_Rp,
Pict->ClipImage.Left, Pict->ClipImage.Top,
PORight - POLeft + 1, POBot - POTop + 1, 0xc0);
#endif
#if 0
printf("l %d t %d r %d b %d\n",POLeft, POTop, PORight, POBot);
printf("width %d height %d\n",
PORight - POLeft + 1, POBot - POTop + 1);
#endif
}
Pict->DataClip.Left = POLeft;
Pict->DataClip.Right = PORight;
Pict->DataClip.Top = POTop;
Pict->DataClip.Bot = POBot;
/* Undraw the old picture */
SetAPen(wind_Rp, 0);
if (Pict->ClipImage.Left > SaveRect.Left) {
FillCheck(Window, SaveRect.Left, SaveRect.Top,
Pict->ClipImage.Left, SaveRect.Bot);
} else
if (Pict->ClipImage.Right < SaveRect.Right) {
FillCheck(Window, Pict->ClipImage.Right, Pict->ClipImage.Top,
SaveRect.Right, SaveRect.Bot);
}
if (Pict->ClipImage.Top > SaveRect.Top) {
FillCheck(Window, SaveRect.Left, SaveRect.Top,
SaveRect.Right, Pict->ClipImage.Top);
} else
if (Pict->ClipImage.Bot < SaveRect.Bot) {
FillCheck(Window, SaveRect.Left, Pict->ClipImage.Bot,
SaveRect.Right, SaveRect.Bot);
}
}
FillCheck(Window,src_x,src_y,dst_x,dst_y)
struct Window *Window;
int src_x,src_y,dst_x,dst_y;
{
if (src_x < 0 || src_x > Window->Width) {
#ifdef DEBUG
printf("Bad Fill src_x %d Width %d\n",
src_x,Window->Width);
#endif
return;
}
if (src_y < 0 || src_y > Window->Height) {
#ifdef DEBUG
printf("Bad Fill src_y %d Height %d\n",
src_y,Window->Height);
#endif
return;
}
if (dst_x < 0 || dst_x > Window->Width) {
#ifdef DEBUG
printf("Bad Fill dst_x %d Width %d\n",
dst_x,Window->Width);
#endif
return;
}
if (dst_y < 0 || dst_y > Window->Height) {
#ifdef DEBUG
printf("Bad Fill dst_y %d Height %d\n",
dst_y,Window->Height);
#endif
return;
}
if (src_x > dst_x) {
#ifdef DEBUG
printf("inverted rect fill\n");
#endif
return;
}
if (src_y > dst_y) {
#ifdef DEBUG
printf("end for end flipped rect fill\n");
#endif
return;
}
RectFill(Window->RPort, src_x,src_y,dst_x,dst_y);
}
AllocScrollTemp( Pict )
register struct Picture *Pict;
{
LONG Plane;
PLANEPTR t;
extern struct MenuItem ScrollSub[];
static ScrollInited;
extern struct NewScreen NewScreen;
if ( !ScrollOn )
return;
#ifdef TEMPWINDOW
NewTemp.Width = Pict->Window->Width;
NewTemp.Height = Pict->Window->Height;
NewTemp.LeftEdge = NewScreen.Width - NewTemp.Width-2;
NewTemp.TopEdge = 0;
NewTemp.Screen = screen;
TempWind = OpenWindow( &NewTemp );
/*WindowToBack( TempWind );*/
return( SUCCESSFUL );
#else
if ( Pict->ScrollRp.BitMap == NULL ) {
InitRastPort( &Pict->ScrollRp );
Pict->ScrollRp.BitMap = &Pict->ScrollBitMap;
}
InitBitMap( &Pict->ScrollBitMap, (long) NewScreen.Depth,
Pict->CountX, Pict->CountY);
for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
t = (PLANEPTR) AllocRaster(Pict->CountX, Pict->CountY);
Pict->ScrollBitMap.Planes[Plane] = (PLANEPTR) t;
if (t == NULL) {
FreeScrollTemp( Pict );
return(UNSUCCESSFUL);
}
}
return(SUCCESSFUL);
#endif
}
FreeScrollTemp( Pict )
struct Picture *Pict;
{
LONG Plane;
if (Pict->Flags & SCROLL_HAPPENED) {
#ifdef TEMPWINDOW
CloseWindow( TempWind );
#else
for (Plane = 0; Plane < Pict->ScrollBitMap.Depth; Plane++) {
if (Pict->ScrollBitMap.Planes[Plane]) {
FreeRaster( (char *) Pict->ScrollBitMap.Planes[Plane],
Pict->CountX,Pict->CountY);
Pict->ScrollBitMap.Planes[Plane] = NULL;
}
}
#endif
}
ResetScrollRects(Pict);
}
ResetScrollRects(Pict)
struct Picture *Pict;
{
Pict->Flags &= ~SCROLL_HAPPENED;
Pict->ImageLoc.Left = Pict->LeftMarg;
Pict->ImageLoc.Top = Pict->TopMarg;
Pict->ImageLoc.Right = Pict->LeftMarg + Pict->CountX - 1;
Pict->ImageLoc.Bot = Pict->TopMarg + Pict->CountY - 1;
Pict->ClipImage = Pict->ImageLoc; /* struct assignment */
}
#ifdef SAFEBLIT
static
SafeClipBlit( src_Wind, src_x, src_y,
dst_Wind, dst_x, dst_y,
width, height, min_terms,
line_no )
struct Window *src_Wind, *dst_Wind;
LONG src_x, src_y, dst_x, dst_y, width, height, min_terms;
LONG line_no;
{
if (src_x < 0 || src_x > src_Wind->Width) {
printf("Line %d Bad blit src_x %d Width %d\n",
line_no,src_x,src_Wind->Width);
return;
}
if (src_y < 0 || src_y > src_Wind->Height) {
printf("Line %d Bad blit src_y %d Height %d\n",
line_no, src_y,src_Wind->Height);
return;
}
if (width < 1 || width > src_Wind->Width) {
printf("Line %d Bad blit width %d\n",line_no, width);
return;
}
if (src_x + width > src_Wind->Width) {
printf("Line %d Blit outside %d Width %d \n",
line_no,src_x+width,src_Wind->Width);
return;
}
if (height < 1 || height > src_Wind->Height) {
printf("Line %d Bad blit height %d\n",line_no,height);
return;
}
if (src_y + height > src_Wind->Height) {
printf("Line %d Blit outside %d Height %d \n",
line_no,src_y+height,src_Wind->Height);
return;
}
ClipBlit( src_Wind->RPort, src_x, src_y,
dst_Wind->RPort, dst_x, dst_y,
width, height, min_terms);
}
#endif
ScrollComplex(Pict)
struct Picture *Pict;
{
int left, top;
int count_x, count_y;
SHORT *NewCounts;
count_x = Pict->Window->Width - Pict->LeftMarg - Pict->RightMarg;
count_y = Pict->Window->Height - Pict->BotMarg - Pict->TopMarg;
NewCounts = (SHORT *) safeAllocMem(count_x*count_y*sizeof(SHORT),MEMF_CLEAR);
if (NewCounts == NULL) {
DispErrMsg("Can't scroll. Out of RAM.",0);
return;
}
ScrollData(Pict, NewCounts, count_x, count_y);
FreeCounts( Pict );
left = Pict->ImageLoc.Left - Pict->LeftMarg;
top = Pict->ImageLoc.Top - Pict->TopMarg;
Pict->RealLow -= Pict->RealGap * left;
Pict->ImagLow -= Pict->ImagGap * top;
Pict->RealHigh = Pict->RealLow + Pict->RealGap * count_x;
Pict->ImagHigh = Pict->ImagLow + Pict->ImagGap * count_y;
FreeScrollTemp(Pict);
Pict->Counts = NewCounts;
Pict->CountX = count_x;
Pict->CountY = count_y;
Pict->CountsSize = count_x * count_y * sizeof(*Pict->Counts);
Pict->CurLine = 0;
}
ScrollData(Pict, NewCounts, width, height)
register struct Picture *Pict;
SHORT *NewCounts;
int width, height;
{
int sr,sc;
register SHORT *s_rowp, *d_rowp, *sp, *dp;
s_rowp = Pict->Counts + Pict->DataClip.Top * Pict->CountX;
d_rowp = NewCounts + (Pict->ClipImage.Top-Pict->TopMarg) * width;
for (sr = Pict->DataClip.Top; sr < Pict->DataClip.Bot; sr++) {
dp = d_rowp + Pict->ClipImage.Left - Pict->LeftMarg;
sp = s_rowp + Pict->DataClip.Left;
for (sc = Pict->DataClip.Left; sc < Pict->DataClip.Right; sc++) {
*dp++ = *sp++;
}
s_rowp += Pict->CountX;
d_rowp += width;
}
}